﻿/**
 * @file lv_demo_long.c
 *
 */

/*********************
 *      INCLUDES
 *********************/
#include "../../lv_demo.h"
#include <stdlib.h>

/*********************
 *      DEFINES
 *********************/
#define GEAM_DIFFICULTY_MAX    2000    // 游戏难度最大值
#define GEAM_DIFFICULTY_MIN    100     // 游戏难度最小值

/**********************
 *      TYPEDEFS
 **********************/

/**********************
 *  STATIC PROTOTYPES
 **********************/
static void zoology_create(lv_obj_t* parent, lv_obj_t** zoology, const lv_img_dsc_t* img, lv_event_cb_t event_cb);
static void zoology_anim(lv_anim_t* anim, lv_obj_t* obj, uint32_t duration, int32_t start, int32_t end, uint8_t hidden);
static void zoology_hidden_cb(lv_anim_t* anim);
static uint8_t srand_0_to_9(void);
static uint8_t srand_0_to_2(void);
static uint8_t srand_0_to_3(void);
static void hit_mouse_check_cb(lv_timer_t* data);
static void reset_geam_cb(lv_event_t* data);
static void mouse_callback(lv_event_t* data);
static void cat_callback(lv_event_t* data);
static void difficulty_adjust_callback(lv_event_t* data);

/**********************
 *  STATIC VARIABLES
 **********************/
static lv_obj_t* head_img;
static lv_obj_t* mouse[4][3];
static lv_obj_t* cat[4][3];
static lv_obj_t* hole[4][3];
static lv_obj_t* integral;
static uint32_t integral_val = 0;
static lv_timer_t* geam_check;
static lv_obj_t* geam_start;
static lv_obj_t* mouse_show;
static lv_obj_t* cat_show;
static lv_obj_t* geam_difficulty_slider;
static int32_t geam_difficulty_val = GEAM_DIFFICULTY_MAX;
static lv_obj_t* difficulty_min_text;
static lv_obj_t* now_difficulty_text;
static lv_obj_t* difficulty_max_text;
static lv_anim_t mouse_hidden_anim;
static lv_anim_t mouse_show_anim;
static lv_anim_t cat_hidden_anim;
static lv_anim_t cat_show_anim;

/**********************
 *      MACROS
 **********************/
LV_IMG_DECLARE(head_portrait);
LV_IMG_DECLARE(cat_img);
LV_IMG_DECLARE(mouse_img);
LV_IMG_DECLARE(mouse_bg_img);

/**********************
 *   GLOBAL FUNCTIONS
 **********************/

void lv_demo_hit_mouse(void)
{
    static lv_coord_t column_dsc[] = { 160, 160, 160, LV_GRID_TEMPLATE_LAST };
    static lv_coord_t row_dsc[]    = { 120, 120, 120, 120, LV_GRID_TEMPLATE_LAST };
    static lv_style_t cat_style;
    static lv_style_t hole_style;
    lv_obj_t* screen = lv_scr_act();
    lv_obj_t* start_abl;
    lv_obj_t* label;

    /* 设置桌面背景 */
    lv_obj_t* img = lv_img_create(screen);
    LV_IMG_DECLARE(desktop_background);
    lv_img_set_src(img, &desktop_background);
    lv_obj_set_layout(img, LV_LAYOUT_GRID);
    lv_obj_set_grid_dsc_array(img, column_dsc, row_dsc);

    integral = lv_label_create(screen);
    lv_obj_align(integral, LV_ALIGN_TOP_RIGHT, 0, 10);
    lv_obj_set_size(integral, 300, 50);
    lv_label_set_text(integral, "integral:0");
    lv_label_set_recolor(integral, true);  // 使能文本重绘色功能

    geam_start = lv_btn_create(screen);
    lv_obj_add_event_cb(geam_start, reset_geam_cb, LV_EVENT_CLICKED, NULL);
    lv_obj_align(geam_start, LV_ALIGN_BOTTOM_RIGHT, -10, -10);
    lv_obj_set_width(geam_start, 300);

    start_abl = lv_label_create(geam_start);
    lv_obj_align(start_abl, LV_ALIGN_CENTER, 0, 0);
    lv_label_set_text(start_abl, "Reset Geam");

    geam_difficulty_slider = lv_slider_create(screen);
    lv_obj_align(geam_difficulty_slider, LV_ALIGN_RIGHT_MID, -20, 0);
    lv_slider_set_range(geam_difficulty_slider, GEAM_DIFFICULTY_MIN, GEAM_DIFFICULTY_MAX);
    lv_slider_set_value(geam_difficulty_slider, GEAM_DIFFICULTY_MAX, LV_ANIM_OFF);
    lv_slider_set_mode(geam_difficulty_slider, LV_SLIDER_MODE_RANGE);
    lv_obj_add_event_cb(geam_difficulty_slider, difficulty_adjust_callback, LV_EVENT_VALUE_CHANGED, NULL);

    label = lv_label_create(screen);
    lv_obj_align_to(label, geam_difficulty_slider, LV_ALIGN_OUT_TOP_MID, -20, -10);
    lv_label_set_text_fmt(label, "Difficulty");

    difficulty_min_text = lv_label_create(screen);
    lv_obj_align_to(difficulty_min_text, geam_difficulty_slider, LV_ALIGN_OUT_BOTTOM_LEFT, -20, 10);
    lv_label_set_text_fmt(difficulty_min_text, "min:%d", GEAM_DIFFICULTY_MIN);

    now_difficulty_text = lv_label_create(screen);
    lv_obj_align_to(now_difficulty_text, geam_difficulty_slider, LV_ALIGN_OUT_BOTTOM_MID, -20, 10);
    lv_label_set_text_fmt(now_difficulty_text, "now:%d", GEAM_DIFFICULTY_MAX);

    difficulty_max_text = lv_label_create(screen);
    lv_obj_align_to(difficulty_max_text, geam_difficulty_slider, LV_ALIGN_OUT_BOTTOM_RIGHT, -20, 10);
    lv_label_set_text_fmt(difficulty_max_text, "max:%d", GEAM_DIFFICULTY_MAX);

    geam_check = lv_timer_create(hit_mouse_check_cb, GEAM_DIFFICULTY_MAX, NULL);

    /* cat style init */
    lv_style_init(&cat_style);
    lv_style_set_bg_color(&cat_style, lv_color_make(0, 180, 255));

    lv_obj_t* hole_obj;
    lv_obj_t* hole_bg_obj;
    
    lv_style_init(&hole_style);
    lv_style_set_img_opa(&hole_style, 150);
    for (uint8_t row = 0; row < 4; row++)
    {
        for (uint8_t col = 0; col < 3; col++)
        {
            hole_bg_obj = lv_label_create(img);
            lv_obj_set_size(hole_bg_obj, 127, 70);
            lv_label_set_text(hole_bg_obj, "");

            hole_obj = lv_img_create(hole_bg_obj);
            lv_img_set_src(hole_obj, &mouse_bg_img);
            lv_obj_align(hole_obj, LV_ALIGN_BOTTOM_MID, 0, 0);
            lv_obj_add_style(hole_obj, &hole_style, LV_STATE_DEFAULT);

            zoology_create(hole_bg_obj, &mouse[row][col], &mouse_img, mouse_callback);
            zoology_create(hole_bg_obj, &cat[row][col], &cat_img, cat_callback);
            lv_obj_add_style(cat[row][col], &cat_style, 0);

            lv_obj_set_grid_cell(hole_bg_obj, LV_GRID_ALIGN_CENTER, col, 1, LV_GRID_ALIGN_CENTER, row, 1);
        }
    }
    uint8_t i = srand_0_to_3(), j = srand_0_to_2();
    mouse_show = mouse[i][j];
    zoology_anim(&mouse_show_anim, mouse_show, 100, 70, 0, false);    // 动画的方式显示老鼠
}

static void zoology_create(lv_obj_t* parent, lv_obj_t** zoology, const lv_img_dsc_t* img, lv_event_cb_t event_cb)
{
    static lv_obj_t* zoology_txt;
    *zoology = lv_imgbtn_create(parent);
    lv_imgbtn_set_src(*zoology, LV_IMGBTN_STATE_RELEASED, NULL, img, NULL);
    lv_obj_align(*zoology, LV_ALIGN_CENTER, 0, 0);
    lv_obj_set_size(*zoology, img->header.w, img->header.h);
    lv_obj_add_flag(*zoology, LV_OBJ_FLAG_HIDDEN);
    lv_obj_add_event_cb(*zoology, event_cb, LV_EVENT_PRESSED, NULL);

    //zoology_txt = lv_label_create(*zoology);
    //lv_label_set_text(zoology_txt, text);
    //lv_obj_align(zoology_txt, LV_ALIGN_CENTER, 0, 0);
}

static void zoology_anim(lv_anim_t *anim, lv_obj_t *obj, uint32_t duration, int32_t start, int32_t end, uint8_t hidden)
{
    /* INITIALIZE AN ANIMATION
     *-----------------------*/
    lv_anim_init(anim);

    /* MANDATORY SETTINGS
     *------------------*/

     /*Set the "animator" function*/
    lv_anim_set_exec_cb(anim, (lv_anim_exec_xcb_t)lv_obj_set_y);

    /*Set the "animator" function*/
    lv_anim_set_var(anim, obj);

    /*Length of the animation [ms]*/
    lv_anim_set_time(anim, duration);

    /*Set start and end values. E.g. 0, 150*/
    lv_anim_set_values(anim, start, end);

    if (hidden)
    {
        lv_anim_set_ready_cb(anim, zoology_hidden_cb);
        lv_anim_set_user_data(anim, obj);
        lv_obj_clear_flag(obj, LV_OBJ_FLAG_CLICKABLE);
    }
    else
    {
        lv_obj_add_flag(obj, LV_OBJ_FLAG_CLICKABLE);
        lv_obj_clear_flag(obj, LV_OBJ_FLAG_HIDDEN);
    }

    /* START THE ANIMATION
    *------------------*/
    lv_anim_start(anim);                             /*Start the animation*/
}

static void zoology_hidden_cb(lv_anim_t* anim)
{
    lv_obj_add_flag(lv_anim_get_user_data(anim), LV_OBJ_FLAG_HIDDEN);
}

static uint8_t srand_0_to_9(void)
{
    uint32_t tmp = 0;
    uint32_t tick = lv_tick_get();
    srand(lv_tick_get());
    // while (lv_tick_get() - tick < 2);
    tmp = rand();
    return tmp % 10;
}

static uint8_t srand_0_to_2(void)
{
    uint32_t tmp = 0;
    uint32_t tick = lv_tick_get();
    srand(lv_tick_get());
    while (lv_tick_get() - tick < 2);
    while (true)
    {
        tmp = rand();
        if ((tmp % 10) % 3 < 3)
        {
            return (tmp % 10) % 3;
        }
    }
}

static uint8_t srand_0_to_3(void)
{
    uint32_t tmp = 0;
    uint32_t tick = lv_tick_get();
    srand(lv_tick_get());
    while (lv_tick_get() - tick < 2);
    while (true)
    {
        tmp = rand();
        if ((tmp % 10) % 4 < 4)
        {
            return (tmp % 10) % 3;
        }
    }
}

static void hit_mouse_check_cb(lv_timer_t* data)
{
    lv_label_set_text_fmt(integral, "#ff0000 you lose,# integral:%d", integral_val);
    zoology_anim(&mouse_hidden_anim, mouse_show, 50, 0, 70, true);
    if (cat_show != NULL)
    {
        zoology_anim(&cat_hidden_anim, cat_show, 50, 0, 70, true);
        cat_show = NULL;
    }
    lv_timer_pause(geam_check);
    printf("GEAM OVER integral_val:%d\r\n", integral_val);
}

static void reset_geam_cb(lv_event_t* data)
{
    uint8_t i = srand_0_to_3(), j = srand_0_to_2();
    mouse_show = mouse[i][j];
    zoology_anim(&mouse_show_anim, mouse_show, 100, 70, 0, false);

    integral_val = 0;
    lv_label_set_text_fmt(integral, "integral:%d", integral_val);

    geam_difficulty_val = lv_slider_get_value(geam_difficulty_slider);
    lv_timer_set_period(geam_check, geam_difficulty_val);
    lv_timer_reset(geam_check);
    lv_timer_resume(geam_check);
}

static void mouse_callback(lv_event_t* data)
{
    uint8_t mouse_i = srand_0_to_3(), mouse_j = srand_0_to_2();
    uint8_t cat_i = 0, cat_j = 0;
    uint8_t zero_nine = 0;

    zoology_anim(&mouse_hidden_anim, mouse_show, 50, 0, 70, true);

    mouse_show = mouse[mouse_i][mouse_j];
    zoology_anim(&mouse_show_anim, mouse_show, 100, 70, 0, false);
    lv_label_set_text_fmt(integral, "integral:%d", ++integral_val);

    geam_difficulty_val -= 10;
    if (geam_difficulty_val < lv_slider_get_left_value(geam_difficulty_slider))
    {
        geam_difficulty_val = lv_slider_get_left_value(geam_difficulty_slider);
    }
    lv_timer_set_period(geam_check, geam_difficulty_val);
    lv_timer_reset(geam_check);
    lv_label_set_text_fmt(now_difficulty_text, "now:%d", geam_difficulty_val);

    if (cat_show != NULL)
    {
        zoology_anim(&cat_hidden_anim, cat_show, 50, 0, 70, true);
        cat_show = NULL;
    }
    zero_nine = srand_0_to_9();
    if (zero_nine == 5 || zero_nine == 8)
    {
        cat_i = srand_0_to_3();
        cat_j = srand_0_to_2();
        if (cat_i != mouse_i || cat_j != mouse_j)
        {
            cat_show = cat[cat_i][cat_j];
            zoology_anim(&cat_show_anim, cat_show, 100, 70, 0, false);
        }
    }
}

static void cat_callback(lv_event_t* data)
{
    lv_label_set_text_fmt(integral, "#ff0000 You hit the cat,# integral:%d", integral_val);
    lv_timer_pause(geam_check);
    zoology_anim(&mouse_hidden_anim, mouse_show, 50, 0, 70, true);
    zoology_anim(&cat_hidden_anim, cat_show, 50, 0, 70, true);
    cat_show = NULL;
}

static void difficulty_adjust_callback(lv_event_t* data)
{
    lv_obj_t* obj = lv_event_get_target(data);
    lv_label_set_text_fmt(difficulty_min_text, "min:%d", lv_slider_get_left_value(obj));
    lv_label_set_text_fmt(now_difficulty_text, "now:%d", lv_slider_get_value(obj));
    lv_label_set_text_fmt(difficulty_max_text, "max:%d", lv_slider_get_value(obj));
}

